package com.andy.qhb.game;

import java.util.Map;

import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.andy.qhb.dao.DaoUtils;
import com.andy.qhb.dao.DbBatch;
import com.andy.qhb.dao.vo.Where;
import com.andy.qhb.entity.BaseEntity;
import com.andy.qhb.entity.UsrFabLog;
import com.andy.qhb.entity.UsrGameInfo;
import com.andy.qhb.entity.UsrGameLog;
import com.andy.qhb.entity.UsrQiangbLog;
import com.andy.qhb.entity.UsrUser;
import com.andy.qhb.game.task.TimerManager;
import com.andy.qhb.utils.GoConstant;
import com.andy.qhb.utils.SendUtil;
import com.andy.qhb.vo.ShowMsg;
import com.google.common.collect.Maps;

public class GameUtils {

	private static Logger logger = LoggerFactory.getLogger(GameUtils.class);
	
	public static void outRoom(GameUser user) {
		if(user == null)return;
		Room room = user.getRoom();
		if(room != null){
			room.removeUser(user);
			SendUtil.send128(user);
		}
		
		saveDb(user.getGameInfo());
		
	}

	public static String genNickName() {
		String firstName = GameConf.firstNames[RandomUtils.nextInt(0, GameConf.firstNames.length)];
		String secondName = GameConf.secondNames[RandomUtils.nextInt(0, GameConf.secondNames.length)];
		return firstName+secondName;
	}

	
	public static void saveDb(BaseEntity... entity){
		try {
			for(BaseEntity en:entity){
				if(en == null)continue;
				if(en.getId() != null){
					if(en instanceof UsrGameInfo){
						DbBatch.upUsrUser((UsrGameInfo) en);
					}else{
						DaoUtils.update(en);
					}
				}else{
					DaoUtils.insert(en);
				}
			}
		} catch (Exception e) {
			logger.error("持久化异常",e);
		}
	}
	
	public static void saveLog(BaseEntity... entity){
		for(BaseEntity en:entity){
			if(en instanceof UsrFabLog){
				DbBatch.svFbGameLog((UsrFabLog) en);
			}else if(en instanceof UsrQiangbLog) {
				DbBatch.svQbGameLog((UsrQiangbLog) en);
			}
		}
	}

	public static void addCoin(Long uid, Integer addCoin) {
		GameUser gameUser = GlobalHttp.getUser(uid);
		if(gameUser != null){
			synchronized (gameUser) {
				gameUser.getGameInfo().addCoin(addCoin);
			}
			DaoUtils.update(gameUser.getGameInfo());
		}else {
			UsrGameInfo gameInfo = DaoUtils.getOne(UsrGameInfo.class,Where.eq("uid", uid));
			gameInfo.addCoin(addCoin);
			DaoUtils.update(gameInfo);
		}
		
	}

	public static GameUser getUsrUser(Long uid) {
		GameUser gameUser = GlobalHttp.getUser(uid);
		if(gameUser == null) {
			UsrUser usr = DaoUtils.get(uid, UsrUser.class);
			if(usr == null)return null;
			gameUser = new GameUser(usr);
		}
		return gameUser;
	}

	/**
	 * 中雷结算
	 * @param uid
	 * @param lei 
	 * @param qhbGame
	 */
	public static void reward(Long uid, int lei, QhbGame qhbGame) {
		GameUser user = GlobalHttp.getUser(uid);
		if(user.miansi()) {
			logger.error("免死：{}-{}-{}",uid,lei,qhbGame.getId());
			return;
		}
		Room room = qhbGame.room();
		if(!room.isNorRoom() && room.creater().getId().equals(uid)) {
			// 群主免死
			logger.error("群主免死：{}-{}-{}",uid,lei,qhbGame.getId());
			return;
		}
		
		int index = (qhbGame.getNum()-7)*3+lei-1;
		int rate = GameConf.leiReward[index];
		int dealCoin = rate*qhbGame.getCoin()/10;
		
		GameUser creater = qhbGame.creater();
		
		userCoinLog(user, -dealCoin, 2,qhbGame.getId());
		userCoinLog(creater, dealCoin, 3,qhbGame.getId());
		
	}
	
	/**
	 * 金币流水记录
	 * @param user null表示系统抽取
	 * @param dealCoin
	 * @param type 0-发包，1-抢包，2-中雷，3-收割，4-退金,5-返佣,6-抢包奖励，7-7发包奖励，8-8发包奖励,
	 * 			9-禁抢5包单雷奖励，10-禁抢6包单雷奖励，11-禁抢5包连环雷奖励，12-禁抢6包连环雷奖励，13-禁抢6包不中奖励
	 * 			14-机器人耗费，15-群主管理费
	 */
	public static void userCoinLog(GameUser user,int dealCoin,int type,Object remark) {
		
		UsrGameInfo gi = null;
		if(user != null) {
			gi = user.getGameInfo();
			if(type == 2) {
				gi.setLoseCount(gi.getLoseCount()+1);
			}else if(type == 3) {
				gi.setWinCount(gi.getWinCount()+1);
			}
		}else {
			gi = new UsrGameInfo();
		}
		UsrGameLog log = new UsrGameLog(gi);
		
		log.setType(type);
		log.setRemark(remark == null?"":remark.toString());
		if(user != null) {
			synchronized (user) {
				gi.addCoin(dealCoin);
			}
		}
		log.setAddCoin(dealCoin);
		
		saveDb(gi,log);
	}


	/**
	 * 抢红包
	 * @param game
	 * @param user
	 */
	public static void qhb(QhbGame game,GameUser user) {
		if(!game.isBy(user) && !game.isEnd()){
			int[] coin = game.nextCoin(user);
			if(coin[1] > 0){
				UsrQiangbLog qiangbLog = new UsrQiangbLog();
				qiangbLog.setCoin(coin[1]);
				qiangbLog.setPid((long) game.getId());
				qiangbLog.setUid(user.getId());
				qiangbLog.setName(user.getNickName());
				qiangbLog.setQorder(coin[0]);
				qiangbLog.setCreateTime(System.currentTimeMillis()/1000);
				boolean isQz = false; // 是否群主
				Room room = game.room();
				if(!room.isNorRoom() && room.creater() == user) {
					isQz = true;
				}
				if(isQz) {
					// 群主免死
					qiangbLog.setMiansi(1);
				}else {
					qiangbLog.setMiansi(user.miansi()?1:0);
				}
				saveLog(qiangbLog);
				
				if(isQz) {
					// 群主免死收取25%管理费
					int glf = (int) (coin[1]*0.25);
					userCoinLog(user, glf, 1,game.getId()+":"+user.getId());
					// 70%给群主，5%抽佣
					int dealCoin = (int) (coin[1]*0.7);
					Global.sysCurrHave.addAndGet(dealCoin );
					userCoinLog(null, dealCoin, 15,game.getId()+":"+user.getId());
				}else {
					if(user.miansi()) {
						Global.sysCurrHave.addAndGet(coin[1]);
					}
					userCoinLog(user, coin[1], 1,game.getId()+":"+user.getId());
				}
				
				
				game.addQlog(qiangbLog);
				
				addQbMsg(game, qiangbLog);
				// 检测抢包奖励
				if(room.getType() == GoConstant.GAME_TYPE_S && qiangbLog.getMiansi()==0) {
					RewardUtil.rewardQb(coin[1],user,game);
				}
				
				if(game.isEnd()){
					// 结算
					if(game.reward()) {
						// 结算中雷提示
						if(room.getType() != GoConstant.GAME_TYPE_F) {
//							addJiesuanMsg(game);
						}
					}
				}
			}else if(user.robot()){
				logger.info("机器人没有抢到：{}-{}",game.isEnd(),coin);
			}
		}
	}
	
	public static void addJiesuanMsg(QhbGame qhbGame) {
		// 提示
		ShowMsg showMsg = new ShowMsg(2,qhbGame.creater().forOther());
		Map<String,Object> gameData = Maps.newHashMap();
		gameData.put("rlog", qhbGame.qlogs());
		showMsg.setMsg(gameData );
		qhbGame.room().addMsg(showMsg);
	}
	
	public static void addQbMsg(QhbGame game,UsrQiangbLog qiangbLog) {
		// 抢包提示
		ShowMsg showMsg = new ShowMsg(3,game.creater().forOther());
		Map<String, Object> gameData = Maps.newHashMap();
		gameData.put("uid", qiangbLog.getUid());
		gameData .put("coin", qiangbLog.getCoin());
		gameData.put("name", qiangbLog.getName());
		gameData.put("isEnd", game.getNum() == qiangbLog.getQorder()+1);
		showMsg.setMsg(gameData );
		game.room().addMsg(showMsg);
	}


	public static QhbGame fab(GameUser user, Integer coin, Integer num, Integer lei, Room room) {
		QhbGame game = new QhbGame(coin,num,lei);
		game.setRoom(room);
		game.setCreater(user);
		
		userCoinLog(user, -coin, 0,game.getId());
		
		Global.addGame(game);
		saveLog(game.toEntity());
		
		if(room.getType() == GoConstant.GAME_TYPE_S) {
			// 扫雷
			if(room.isNorRoom()) {
				// 免死先抢
				TimerManager.schedule(()->{
					qhb(game, RobotManager.getMiansi());
				},10);
			}else {
				// 群主自动抢
				TimerManager.schedule(()->{
					qhb(game, room.creater());
				},10);
			}
			
			for(int i=0;i<game.getNum()-1;i++) {
				TimerManager.schedule(()->{
					try {
						GameUser robot = RobotManager.getRobot();
						while(game.isBy(robot)) {
							robot = RobotManager.getRobot();
						}
						qhb(game, robot);
					} catch (Exception e) {
						logger.error("机器人抢包异常",e);
					}
				}, RandomUtils.nextInt(7, 15)*1000);
			}
		}else if(room.getType() == GoConstant.GAME_TYPE_J){
			// 禁抢
			TimerManager.schedule(()->{
				try {
					for(int i=0;i<game.getNum();i++) {
						qhb(game, RobotManager.getRobot());
					}
				} catch (Exception e) {
					logger.error("机器人抢包异常",e);
				}
			}, 10);
		}
		
		ShowMsg showMsg = new ShowMsg(0,user.forOther());
		Map<String,Object> gameData = Maps.newHashMap();
		gameData.put("pid", game.getId());
		gameData.put("coin", game.getCoin());
		gameData.put("num", game.getNum());
		gameData.put("lei", game.getLei());
		showMsg.setMsg(gameData );
		room.addMsg(showMsg);
		return game;
	}

}
